
//#include "structure/mygraph.h"

///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 21 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////

#include "MyFrame.h"

///////////////////////////////////////////////////////////////////////////

MyFrame::MyFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	
	m_statusBar1 = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
	menuBar = new wxMenuBar( 0 );
	fileMenu = new wxMenu();
	wxMenuItem* openItem;
	openItem = new wxMenuItem( fileMenu, ID_Open, wxString( wxT("Open") ) , wxEmptyString, wxITEM_NORMAL );
	fileMenu->Append( openItem );
	
	menuBar->Append( fileMenu, wxT("File") );
	
	instMenu = new wxMenu();
	wxMenuItem* mapItem;
	mapItem = new wxMenuItem( instMenu, ID_Find, wxString( wxT("Map") ) , wxEmptyString, wxITEM_NORMAL );
	instMenu->Append( mapItem );
	
	menuBar->Append( instMenu, wxT("Instance") );
	
	this->SetMenuBar( menuBar );
	
	
	layout = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Xdl2LL") ), wxVERTICAL );
	
	wxStaticBoxSizer* sbSizer2;
	sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Files") ), wxHORIZONTAL );
	
	xdlText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB|wxTE_READONLY );
	sbSizer2->Add( xdlText, 1, wxEXPAND|wxALL, 5 );
	
	llText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB|wxTE_READONLY );
	sbSizer2->Add( llText, 1, wxALL|wxEXPAND, 5 );
	
	layout->Add( sbSizer2, 1, wxEXPAND, 5 );


//        infoSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Info") ), wxVERTICAL );
//
//        instGrid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 200));
//        infoSizer->Add(instGrid, 1, wxALL|wxEXPAND, 5);
//
//	layout->Add( infoSizer, 0, wxALIGN_BOTTOM|wxEXPAND, 5 );
		
	
	this->SetSizer( layout );
	this->Layout();
	
	// Connect Events
	this->Connect( openItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MyFrame::OnOpen ) );
	this->Connect( mapItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MyFrame::OnMap ) );
	llText->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( MyFrame::OnDouble ), NULL, this );
	llText->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( MyFrame::OnLeftUp ), NULL, this );
        //instGrid->Connect( wxEVT_GRID_CELL_CHANGE, wxGridEventHandler(MyFrame::OnCellEdit), NULL, this);
}

MyFrame::~MyFrame()
{
	// Disconnect Events
	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MyFrame::OnOpen ) );
	this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MyFrame::OnMap ) );
	llText->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( MyFrame::OnDouble ), NULL, this );
	llText->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( MyFrame::OnLeftUp ), NULL, this );
//        instGrid->Disconnect( wxEVT_GRID_CELL_CHANGE, wxGridEventHandler(MyFrame::OnCellEdit), NULL, this);

}

void MyFrame::OnOpen(wxCommandEvent& event)
{

    wxString fileName = wxFileSelector(wxT("Open"));
    if(fileName.IsEmpty() == false)
    {
        xdlText->SetDefaultStyle(*wxRED);
        xdlText->LoadFile(fileName);
        char tmp[100];// = (const char*)fileName.mb_str(wxConvUTF8);
        strcpy( tmp, (const char*)fileName.mb_str(wxConvUTF8) );

        fileName.Remove(fileName.Find( wxT(".xdl") ));
        fileName.Append( wxT(".ll") );
        llText->LoadFile(fileName);

        filebuf fb;
        fb.open(tmp, ios::in);
        istream is(&fb);
	xdl = Parser(&is);
	if(xdl.parse()==0)
	{
		
	}
        fb.close();

    }

}

void MyFrame::OnMap(wxCommandEvent& event)
{
   
    MyMapTree* mapTree = new MyMapTree(this);
    mapTree->SetTitle(_T("Mapping"));
//    mapTree->construct(&xdl.g);
    mapTree->Show(true);

}

void MyFrame::OnLeftUp(wxMouseEvent& event)
{
    wxString selection( llText->GetStringSelection());
    if(!selection.IsEmpty())
    {
       resetTextStyle(xdlText);
       //trashText->Clear();
       wxString token = tokenize(selection, _T("Block="));
       retrieveInfoByVertex(&token);
    }

}

void MyFrame::OnDouble(wxMouseEvent& event)
{
    long x,y;
    llText->PositionToXY(llText->GetInsertionPoint(), &x, &y);
    setSelectionLine(y);
}



void MyFrame::retrieveInfoByVertex(wxString* site)
{
    /* retrieve the vertex line */
    long line = xdl.g.getVertexLine( xdl.g.getVertexBySite( &string( site->mb_str() ) ) );

    if(line != 0)
    {
        line--;
        changeRowStyle(line);
        xdlText->SetInsertionPoint(xdlText->XYToPosition(0, line) );
        /* retrieve the edge line that vertex refers to */
        vector< pair<int,int> >* list_net = xdl.g.getNetLines(xdl.g.getVertexBySite( &string( site->mb_str() ) ));
        for(int i=0; i < list_net->size(); i++)
        {
            long lng;
            list_net->at(i).first--;
            list_net->at(i).second--;
            lng = list_net->at(i).first;
            changeRowStyle(lng );
            lng = list_net->at(i).second;
            changeRowStyle(lng );
        }
    }
    else
        xdlText->SetInsertionPoint(line);
}


void MyFrame::retrieveInfoByVertex(Vertex target)
{
    /* retrieve the vertex line */
    long line = xdl.g.getVertexLine( target );

    if(line != 0)
    {
        line--;
        changeRowStyle(line);
        xdlText->SetInsertionPoint(xdlText->XYToPosition(0, line) );
        /* retrieve the edge line that vertex refers to */
        vector< pair<int,int> >* list_net = xdl.g.getNetLines(target);
        for(int i=0; i < list_net->size(); i++)
        {
            long lng;
            list_net->at(i).first--;
            list_net->at(i).second--;
            lng = list_net->at(i).first;
            changeRowStyle(lng );
            lng = list_net->at(i).second;
            changeRowStyle(lng );
        }
    }
    else
        xdlText->SetInsertionPoint(line);
}

void MyFrame::changeRowStyle(long line_number)
{
    wxString found_line = xdlText->GetLineText(line_number);
    long start;

    /* Begin highlighting */
    start = xdlText->XYToPosition(0, line_number);

    xdlText->SetStyle(start, start + found_line.Length(), wxTextAttr(*wxRED, *wxLIGHT_GREY) );
    //xdlText->SetInsertionPoint(start);
}

void MyFrame::setSelectionLine(long line_number)
{
    long start = llText->XYToPosition(0, line_number);
    long end = llText->GetLineText(line_number).Length();
    llText->SetSelection(start, start+end);
}


void MyFrame::resetTextStyle(wxTextCtrl* ctrlText )
{
    /* Cleaning the previous selection */
    int line_number = ctrlText->GetNumberOfLines();
    int line_length = ctrlText->GetLineLength(--line_number);
    --line_length;

    ctrlText->SetStyle( 0, ctrlText->XYToPosition(--line_length, --line_number), wxTextAttr(*wxBLACK, *wxWHITE) );
}

wxString MyFrame::tokenize(wxString selection, wxString selector)
{
    wxStringTokenizer tokens(selection, wxT(" "));
    wxString pass;
    while( tokens.HasMoreTokens() )
    {
        wxString token = tokens.GetNextToken();
        if(token.StartsWith(selector))
        {
            pass = token.SubString(selector.Length(), token.Length());
        }
        //else trashText->AppendText(token.SubString(0, token.Length())+_T(" "));
    }

    return pass;
}

/*
void MyFrame::createGrid()
{
    vert_bm = xdl.g.getVertexMap();
    int numRows = vert_bm->size();
    instGrid->CreateGrid(numRows, 3);
    
    //instGrid->EnableEditing(false);
    instGrid->SetColLabelValue(0, _T("Instance"));
    instGrid->SetColLabelValue(1, _T("Block"));
    instGrid->SetColLabelValue(2, _T("Select on XDL"));

    wxGridCellAttr *attrBool = new wxGridCellAttr;
    attrBool->SetEditor(new wxGridCellBoolEditor);
    attrBool->SetRenderer(new wxGridCellBoolRenderer);
    instGrid->SetColAttr(2, attrBool);


    //instGrid->SetColFormatBool(2);
    int i=0;
    typedef bm_vertex::right_map::const_iterator right_const_iterator;
    for(right_const_iterator iter = vert_bm->right.begin(), iend = vert_bm->right.end(); iter != iend; ++iter)
    {
        instGrid->SetCellValue(i, 0, wxString(iter->first.c_str(), wxConvUTF8));
        instGrid->SetCellValue(i, 1, wxString(xdl.g.getVertexSite(iter->second).c_str(), wxConvUTF8));
        
        i++;
    }


    instGrid->AutoSize();
    instGrid->Fit();
    
    
}
*/

/*
void MyFrame::OnCellEdit(wxGridEvent& event)
{

    if(event.GetCol() == 2)
    {
        string inst(instGrid->GetCellValue(event.GetRow(), 0).mb_str());
        Vertex target = vert_bm->right.at(inst);
        retrieveInfoByVertex(target);

    }


}
*/